package com.bcts.rrh.drawingboard;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
import android.opengl.GLUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;

import com.bcts.rrh.drawingboard.shapeview.Ball;
import com.bcts.rrh.drawingboard.shapeview.Cube;
import com.bcts.rrh.drawingboard.shapeview.ShapeList;
import com.bcts.rrh.drawingboard.shapeview.Shape_3d;
import com.bcts.rrh.drawingboard.shapeview.ZhuiTi;
import com.bcts.rrh.drawingboard.utils.IsIntersectantUtil;
import com.bcts.rrh.drawingboard.utils.RotateUtil;

import static com.bcts.rrh.drawingboard.Constants.*;
import static com.bcts.rrh.drawingboard.utils.IsIntersectantUtil.isLineCrossPlaneZ;

public class testView extends GLSurfaceView {
    private static final int NONE = 0;// 原始
    public static final int STROKE_TYPE_ERASER = 1;//橡皮檫模式
    public static final int STROKE_TYPE_DRAW = 2;//画笔模式
    public static final int STROKE_TYPE_LINE = 3;//划线模式
    public static final int STROKE_TYPE_CIRCLE = 4;//画圆模式
    public static final int STROKE_TYPE_triangle = 5;//画三角形形模式
    public static final int STROKE_TYPE_RECTANGLE = 6;//画矩形模式
    public static final int MOVE = 7;// 拖动
    public static final int ROTATE=8;// 旋转
    public static final int ZOOM = 9;// 放大
    public static final int FILL=10;//  填充
    public static final int ROTATE_3D=11;//3D旋转
    public static int strokeType=STROKE_TYPE_CIRCLE;//模式选择，橡皮檫1，画笔2，线条3，圆形4，矩形5等,初始状态是画笔状态
    public int TriangleState=0;//画三角形的状态，0代表不用画，1代表画第一条边，2代表画整个三角形

    public int screenWidth, screenHeight;//屏幕的高度和宽度

    public testView(Context context) {
        super(context);
        setScreenWH();
        mRenderer = new SceneRenderer();	//创建场景渲染器
        setRenderer(mRenderer);				//设置渲染器
        setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);//设置渲染模式为主动渲染
        alBN=new ArrayList<Shape_3d>();
        alDistance=new ArrayList<Float>();
    }

    public SceneRenderer mRenderer;//声明渲染器
    //ShapeList alBN;

    Shape_3d bnShape;//声明形状
    float cx=0;//摄像机x位置
    float cy=1;//摄像机y位置
    float cz=0;//摄像机z位置

    float tx;////目标点x位置
    float ty;//目标点y位置
    float tz;//目标点z位置
    float left;//视角的值
    float right;
    float top;
    float bottom;
    float near;
    float far;
    float cameraAlpha=70;//摄像机角度

    {
        tx=(float)(cx-CAMERA_DISTANCE*Math.sin(Math.toRadians(cameraAlpha)));
        ty=cy;
        tz=(float)(cz-CAMERA_DISTANCE*Math.cos(Math.toRadians(cameraAlpha)));
    }

    ArrayList<Shape_3d> alBN;//物体列表
    ArrayList<Float> alDistance;//离摄像机的距离



    private void setScreenWH() {//获取屏幕的宽度和高度
        DisplayMetrics dm =  this.getResources().getDisplayMetrics();
        screenWidth = dm.widthPixels;
        screenHeight = dm.heightPixels;
    }
    public void setMode(int mode)//设置模式
    {
        this.strokeType=mode;
    }

    @Override
    public boolean onTouchEvent(MotionEvent e)
    {
        float y = e.getY();
        float x = e.getX();
        switch(e.getAction())
        {
            case MotionEvent.ACTION_DOWN:
                touch_start(x, y);
                break;
            case MotionEvent.ACTION_MOVE://用户手指的移动
                touch_move(x, y);
                break;
            case MotionEvent.ACTION_UP://用户的手指离开屏幕
                //draw();
                touch_up(x, y);
                break;
        }

        return true;
    }

    private void touch_start(float x, float y) {

        switch (strokeType){
            case STROKE_TYPE_CIRCLE://画球
                //bnShape=new Ball(BALL_R,textureId,-5f,5f,1.0f);//创建球
                float[] bPosition=RotateUtil.calculateABPosition//根据触点返回射线
                        (
                                x, //触屏X坐标
                                y, //触屏Y坐标
                                screenWidth, //屏幕宽度
                                screenHeight, //屏幕长度
                                left, //视角left值
                                top, //视角top值
                                near, //视角near值
                                far,
                                cameraAlpha,//摄像机角度
                                cx,
                                cy,
                                cz
                        );
                float[] pointOnFace=isLineCrossPlaneZ(-5f,bPosition[0],bPosition[1],bPosition[2], bPosition[3],bPosition[4],bPosition[5]);	//与平面相交点
                //bnShape=new Ball(BALL_R,mRenderer.textureId,pointOnFace[0],pointOnFace[1],pointOnFace[2]);//创建球
                alBN.add(bnShape);
                break;
            case STROKE_TYPE_triangle://画锥体
                break;
            case STROKE_TYPE_RECTANGLE://画立方体
                break;
            case MOVE://移动
                break;
            case ROTATE://旋转
                break;
            case ZOOM://放大

                alDistance.clear();//清空列表
                float bodyDistance = Float.POSITIVE_INFINITY;//记录物体距离
                int bodyFlag = 0;//记录物体的标志位

                for (int i = 0; i < alBN.size(); i++) {
                alBN.get(i).setHilight(false);
                float minMax[] = alBN.get(i).findMinMax();//获得长宽高
                float mid[] = alBN.get(i).findMid();//获取中心点位置
                float[] bPosition1 = RotateUtil.calculateABPosition
                        (
                                x, //触屏X坐标
                                y, //触屏Y坐标
                                screenWidth, //屏幕宽度
                                screenHeight, //屏幕长度
                                left, //视角left值
                                top, //视角top值
                                near, //视角near值
                                far,
                                cameraAlpha,//摄像机角度
                                cx,
                                cy,
                                cz
                        );
                float tempDistance = IsIntersectantUtil.isIntersectant
                        (
                                mid[0], mid[1], mid[2], //物体中心点位置
                                minMax[0] / 2, minMax[1] / 2, minMax[2] / 2, //长 宽 高
                                bPosition1[0], bPosition1[1], bPosition1[2],//A点位置
                                bPosition1[3], bPosition1[4], bPosition1[5]//B点位置
                        );
                alDistance.add(tempDistance);
            }
                for (int i = 0; i < alDistance.size(); i++) {
                    float tempA = alDistance.get(i);
                    if (tempA < bodyDistance) {
                        bodyDistance = tempA;//记录最小值
                        bodyFlag = i;//记录最小值索引
                    }
                }

                Log.d("bodyDistance", bodyDistance + "");

                if (!Float.isInfinite(bodyDistance)) {
                    alBN.get(bodyFlag).setHilight(true);//调用调整大小的方法
                    Log.d("hi", bodyFlag + "|" + alBN.get(bodyFlag).getClass().toString());
                }
                break;

        }

    }

    private void touch_move(float x, float y) {
    }

    private void touch_up(float x, float y) {
    }

    public class SceneRenderer implements GLSurfaceView.Renderer
    {
        public int cubeId;//声明立方体ID
        public int textureId;//声明球ID
        public int textureZId;//晶体纹理ID

        //Shape_3d bnShape;//声明形状
        //Cube cube;//声明对象
        @Override
        public void onDrawFrame(GL10 gl) {
            // TODO Auto-generated method stub
            //清除颜色缓存
            gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
            //设置当前矩阵为模式矩阵
            gl.glMatrixMode(GL10.GL_MODELVIEW);
            //设置当前矩阵为单位矩阵
            gl.glLoadIdentity();
            //设置camera位置
            GLU.gluLookAt
                    (
                            gl,
                            cx,   //摄像机的X位置
                            cy, 	//摄像机的Y位置
                            cz,   //摄像机的Z位置
                            tx, 	//目标点X
                            ty,   //目标点Y
                            tz,   //目标点Z
                            0, //UP位置
                            1,
                            0
                    );

            gl.glPushMatrix();//保护变换矩阵现场
            //将list中的所有形状遍历
            for(int i=0;i<alBN.size();i++)
            {
                gl.glPushMatrix();
                alBN.get(i).drawSelf(gl);
                gl.glPopMatrix();
            }
            gl.glPopMatrix();
        }

        @Override
        public void onSurfaceChanged(GL10 gl, int width, int height) {
            // TODO Auto-generated method stub
            //设置视窗大小及位置
            gl.glViewport(0, 0, width, height);
            //设置当前矩阵为投影矩阵
            gl.glMatrixMode(GL10.GL_PROJECTION);
            //设置当前矩阵为单位矩阵
            gl.glLoadIdentity();
            //计算透视投影的比例
            float ratio = (float) width / height;
            left=right=ratio*0.5f;
            top=bottom=0.5f;
            near=1;
            far=100;
            //调用此方法计算产生透视投影矩阵
            gl.glFrustumf(-left,right,-bottom,top, near, far);
            //gl.glOrthof(-ratio, ratio, -1, 1, 1, 10);//调用此方法计算产生正交投影矩阵
        }

        @Override
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            // TODO Auto-generated method stub
            //关闭抗抖动
            gl.glDisable(GL10.GL_DITHER);
            //设置特定Hint项目的模式，这里为设置为使用快速模式
            gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST);
            //设置屏幕背景色黑色RGBA
            gl.glClearColor(25.0f/255.0f,67.0f/255.0f,56.0f/255.0f,1.0f);
            //设置着色模型为平滑着色
            gl.glShadeModel(GL10.GL_SMOOTH);
            //启用深度测试
            gl.glEnable(GL10.GL_DEPTH_TEST);
            //设置为打开背面剪裁
            //gl.glEnable(GL10.GL_CULL_FACE);

            cubeId=initTexture(gl,R.drawable.stone);//初始化立方体纹理ID
            textureId=initTexture(gl,R.drawable.basketball);//初始化纹理ID
            textureZId=initTexture(gl,R.drawable.robot);


            //alBN.addBallShape(testView.this,200,250);
            /*bnShape=new Cube(cubeId,CUBE_X,CUBE_Y,CUBE_Z,-10f,0f,-4.0f);//创建立方体对象
            alBN.add(bnShape);
            bnShape=new Ball(BALL_R,textureId,-5f,5f,1.0f);//创建球
            alBN.add(bnShape);
            bnShape=new ZhuiTi(textureZId,ZHUITI_X,ZHUITI_Y,ZHUITI_Z,-10f,0f,1.0f);//创建晶体
            alBN.add(bnShape);
            bnShape=new Cube(cubeId,CUBE_X,CUBE_Y,CUBE_Z,-10f,0f,4.0f);
            //new Cylinder(cubeId,CYLINDER_LENGTH,CYLINDER_CIRCLE_RADIUS,CYLINDER_DEGREE_SPAN,CYLINDER_COL,-10f,0f,4.0f);//创建圆柱体
            alBN.add(bnShape);
            bnShape=new ZhuiTi(textureZId,ZHUITI_X,ZHUITI_Y,ZHUITI_Z,10f,0f,1.0f);//创建晶体
            alBN.add(bnShape);
            bnShape=new Cube(cubeId,CUBE_X,CUBE_Y,CUBE_Z,10f,0f,-4.0f);//创建立方体对象
            alBN.add(bnShape);
            bnShape=new Ball(BALL_R,textureId,20f,0,-4.0f);//创建球
            alBN.add(bnShape);

            bnShape=new Ball(BALL_R,textureId,-5f,0,1.0f);//创建球
            alBN.add(bnShape);
            bnShape=new ZhuiTi(textureZId,ZHUITI_X,ZHUITI_Y,ZHUITI_Z,8f,0f,1.0f);//创建晶体
            alBN.add(bnShape);*/
        }

    }
    //初始化纹理
    public int initTexture(GL10 gl,int drawableId)
    {
        //生成纹理ID
        int[] textures = new int[1];
        gl.glGenTextures(1, textures, 0);//提供未使用的纹理对象名称
        int textureId=textures[0];
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);//创建和使用纹理对象
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);//指定放大缩小过滤方法
        gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,GL10.GL_CLAMP_TO_EDGE);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,GL10.GL_CLAMP_TO_EDGE);

        InputStream is = this.getResources().openRawResource(drawableId);
        Bitmap bitmapTmp;
        try
        {
            bitmapTmp = BitmapFactory.decodeStream(is);
        }
        finally
        {
            try
            {
                is.close();
            }
            catch(IOException e)
            {
                e.printStackTrace();
            }
        }
        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmapTmp, 0);//定义二维纹理
        bitmapTmp.recycle();

        return textureId;
    }
}
